feat(providers): add DigitalOcean and Scaleway presets - #872
Conversation
📝 WalkthroughWalkthroughThe PR adds DigitalOcean Serverless Inference and Scaleway Generative APIs as provider presets. It adds bounded, allowlisted model discovery, routing and parity tests, Scaleway directory metadata, and updates English and localized documentation. ChangesProvider registry and discovery
Provider behavior and validation
Documentation
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant ProviderRegistry
participant ModelsEndpoint
participant ModelRouter
Client->>ProviderRegistry: select DigitalOcean or Scaleway preset
ProviderRegistry->>ModelsEndpoint: request authenticated model list
ModelsEndpoint-->>ProviderRegistry: bounded model response
ProviderRegistry->>ProviderRegistry: apply provider allowlist
ProviderRegistry-->>Client: expose compatible models
Client->>ModelRouter: send model request
ModelRouter->>ModelsEndpoint: route to fixed chat-completions endpoint
Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs-site/src/content/docs/guides/providers.md`:
- Around line 269-273: Synchronize the Scaleway discovery sections in
docs-site/src/content/docs/guides/providers.md:269-273,
docs-site/src/content/docs/ja/guides/providers.md:192-195,
docs-site/src/content/docs/ko/guides/providers.md:191-194,
docs-site/src/content/docs/ru/guides/providers.md:202-206, and
docs-site/src/content/docs/zh-cn/guides/providers.md:180-183. In each locale,
identify the documented Chat Completions allowlist, authenticated-model
intersection, bounded discovery, and fail-closed exclusion of unknown,
Responses-only, embeddings, transcription, and other media models; additionally
update the Korean section to state that Project-qualified URLs and dedicated
deployments require a custom provider.
In `@src/providers/registry.ts`:
- Around line 586-598: Remove "gpt-oss-120b" from the
SCALEWAY_SERVERLESS_CHAT_MODELS catalog in src/providers/registry.ts. Update the
mixed-catalog discovery assertion in
tests/digitalocean-scaleway-provider.test.ts to verify that this model is
excluded while preserving the existing supported-model assertions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 84fd0f19-db85-41cb-bed6-8e27ea1a55c0
📒 Files selected for processing (16)
docs-site/src/content/docs/getting-started/quickstart.mddocs-site/src/content/docs/guides/providers.mddocs-site/src/content/docs/ja/getting-started/quickstart.mddocs-site/src/content/docs/ja/guides/providers.mddocs-site/src/content/docs/ko/getting-started/quickstart.mddocs-site/src/content/docs/ko/guides/providers.mddocs-site/src/content/docs/ru/getting-started/quickstart.mddocs-site/src/content/docs/ru/guides/providers.mddocs-site/src/content/docs/zh-cn/getting-started/quickstart.mddocs-site/src/content/docs/zh-cn/guides/providers.mdsrc/providers/free-directory.tssrc/providers/registry.tstests/digitalocean-scaleway-provider.test.tstests/fixtures/digitalocean-models.jsontests/fixtures/scaleway-models.jsontests/provider-registry-parity.test.ts
| **Scaleway discovery.** The preset intersects the authenticated model list with Scaleway's current | ||
| Serverless chat-model allowlist, excluding embeddings and audio transcription, and caps discovery | ||
| at 128 KiB and 128 raw rows. It uses the default Project's shared endpoint; project-qualified URLs | ||
| and dedicated deployments require a custom provider. Create an API key in the | ||
| [Scaleway console](https://console.scaleway.com/generative-api). |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Complete the Scaleway discovery contract in every locale.
These sections describe a chat-model allowlist but do not explicitly identify the documented Chat Completions allowlist or fail-closed exclusion of unknown, Responses-only, and other media models. The Korean section also omits the custom-provider requirement for Project-qualified URLs and dedicated deployments.
docs-site/src/content/docs/guides/providers.md#L269-L273: State the documented Chat Completions allowlist and explicit fail-closed exclusions.docs-site/src/content/docs/ja/guides/providers.md#L192-L195: State the documented Chat Completions allowlist and explicit fail-closed exclusions.docs-site/src/content/docs/ko/guides/providers.md#L191-L194: Add the documented Chat Completions and fail-closed exclusions, and state that Project-qualified URLs and dedicated deployments require a custom provider.docs-site/src/content/docs/ru/guides/providers.md#L202-L206: State the documented Chat Completions allowlist and explicit fail-closed exclusions.docs-site/src/content/docs/zh-cn/guides/providers.md#L180-L183: State the documented Chat Completions allowlist and explicit fail-closed exclusions.
As per path instructions, localized provider catalogs must stay synchronized and document authenticated allowlist intersection, bounded discovery, fail-closed exclusions, and provider-specific endpoint scope.
📍 Affects 5 files
docs-site/src/content/docs/guides/providers.md#L269-L273(this comment)docs-site/src/content/docs/ja/guides/providers.md#L192-L195docs-site/src/content/docs/ko/guides/providers.md#L191-L194docs-site/src/content/docs/ru/guides/providers.md#L202-L206docs-site/src/content/docs/zh-cn/guides/providers.md#L180-L183
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs-site/src/content/docs/guides/providers.md` around lines 269 - 273,
Synchronize the Scaleway discovery sections in
docs-site/src/content/docs/guides/providers.md:269-273,
docs-site/src/content/docs/ja/guides/providers.md:192-195,
docs-site/src/content/docs/ko/guides/providers.md:191-194,
docs-site/src/content/docs/ru/guides/providers.md:202-206, and
docs-site/src/content/docs/zh-cn/guides/providers.md:180-183. In each locale,
identify the documented Chat Completions allowlist, authenticated-model
intersection, bounded discovery, and fail-closed exclusion of unknown,
Responses-only, embeddings, transcription, and other media models; additionally
update the Korean section to state that Project-qualified URLs and dedicated
deployments require a custom provider.
Source: Path instructions
| const SCALEWAY_SERVERLESS_CHAT_MODELS = [ | ||
| "glm-5.2", | ||
| "gpt-oss-120b", | ||
| "qwen3.6-35b-a3b", | ||
| "qwen3.5-397b-a17b", | ||
| "qwen3-235b-a22b-instruct-2507", | ||
| "qwen3-coder-30b-a3b-instruct", | ||
| "gemma-4-26b-a4b-it", | ||
| "llama-3.3-70b-instruct", | ||
| "mistral-medium-3.5-128b", | ||
| "mistral-small-3.2-24b-instruct-2506", | ||
| "pixtral-12b-2409", | ||
| ] as const; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
echo '--- registry context ---'
sed -n '540,630p' src/providers/registry.ts
echo '--- test context ---'
sed -n '210,275p' tests/digitalocean-scaleway-provider.test.ts
echo '--- model and route references ---'
rg -n -C 3 'gpt-oss-120b|SCALEWAY_SERVERLESS_CHAT_MODELS|openai-chat|Responses API|responses' src testsRepository: lidge-jun/opencodex
Length of output: 50376
🌐 Web query:
Scaleway supported models gpt-oss-120b Chat Completions tool calling Responses API
💡 Result:
The gpt-oss-120b model is supported on Scaleway's platform [1][2]. However, official documentation explicitly states that the standard Chat Completions API does not currently support tool-calling for this specific model [1]. To access tool-calling features for gpt-oss-120b, it is recommended to use the Responses API [1][3][4]. While the Chat Completions API is generally used for conversational interfaces and supports tool-calling for many other models [5][6], the Responses API is the required path to utilize the full range of features available for gpt-oss-120b [1][3]. In summary: - Chat Completions API: Supported for general queries but lacks tool-calling support for gpt-oss-120b [1]. - Responses API: Recommended for gpt-oss-120b to enable tool-calling and access all model features [1][3][4].
Citations:
- 1: https://www.scaleway.com/en/docs/generative-apis/reference-content/supported-models/
- 2: https://www.scaleway.com/en/generative-apis/
- 3: https://www.scaleway.com/en/docs/generative-apis/reference-content/openai-compatibility/
- 4: https://www.scaleway.com/en/docs/generative-apis/how-to/query-language-models/
- 5: https://www.scaleway.com/en/docs/generative-apis/how-to/use-function-calling/
- 6: https://www.scaleway.com/en/developers/api/generative-apis
🏁 Script executed:
#!/bin/bash
set -eu
echo '--- registry allowlist and nearby definitions ---'
sed -n '560,615p' src/providers/registry.ts
echo '--- exact gpt-oss references ---'
rg -n -C 8 'gpt-oss-120b' src/providers/registry.ts tests/digitalocean-scaleway-provider.test.ts
echo '--- relevant test block ---'
sed -n '220,265p' tests/digitalocean-scaleway-provider.test.ts
echo '--- registry discovery and route construction symbols ---'
rg -n 'SCALEWAY_SERVERLESS_CHAT_MODELS|digitalocean|scaleway|openai-chat|routed|catalog|models' src/providers/registry.ts tests/digitalocean-scaleway-provider.test.tsRepository: lidge-jun/opencodex
Length of output: 39346
🏁 Script executed:
#!/bin/bash
set -eu
python3 - <<'PY'
from pathlib import Path
for name in ("src/providers/registry.ts", "tests/digitalocean-scaleway-provider.test.ts"):
print(f"--- {name}: matching lines with numbers ---")
for i, line in enumerate(Path(name).read_text().splitlines(), 1):
if any(term in line for term in ("gpt-oss-120b", "SCALEWAY_SERVERLESS_CHAT_MODELS", "scalewayModels", "openai-chat")):
start = max(1, i - 6)
end = i + 10
lines = Path(name).read_text().splitlines()
for j in range(start, min(end, len(lines)) + 1):
print(f"{j}: {lines[j-1]}")
print()
PYRepository: lidge-jun/opencodex
Length of output: 50375
🏁 Script executed:
#!/bin/bash
set -eu
echo '--- Scaleway fixture entry ---'
rg -n -C 5 'gpt-oss-120b' tests/fixtures/scaleway-models.json
echo '--- tool-request test ---'
sed -n '255,315p' tests/digitalocean-scaleway-provider.test.ts
echo '--- OpenAI Chat adapter request construction ---'
rg -n -C 12 'tools|tool_choice|parallel_tool_calls|buildRequest' src/adapters/openai-chat.ts
echo '--- relevant provider contract types and routing metadata ---'
rg -n -C 8 'parallelToolCalls|adapter.*openai-chat|modelDiscovery|filter' src/types.ts src/providers src/codexRepository: lidge-jun/opencodex
Length of output: 50376
🏁 Script executed:
#!/bin/bash
set -eu
python3 - <<'PY'
import json
from pathlib import Path
fixture = json.loads(Path("tests/fixtures/scaleway-models.json").read_text())
rows = fixture.get("data", fixture) if isinstance(fixture, dict) else fixture
for row in rows:
if isinstance(row, dict) and row.get("id") == "gpt-oss-120b":
print(json.dumps(row, indent=2, sort_keys=True))
PYRepository: lidge-jun/opencodex
Length of output: 254
Exclude gpt-oss-120b from Scaleway’s tool-capable catalog.
Scaleway does not support tool calling for this model through Chat Completions. The openai-chat adapter sends tools to /chat/completions, so routed agent requests fail. Remove it from SCALEWAY_SERVERLESS_CHAT_MODELS and update tests/digitalocean-scaleway-provider.test.ts to assert that mixed-catalog discovery excludes it.
📍 Affects 2 files
src/providers/registry.ts#L586-L598(this comment)tests/digitalocean-scaleway-provider.test.ts#L247-L251
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/providers/registry.ts` around lines 586 - 598, Remove "gpt-oss-120b" from
the SCALEWAY_SERVERLESS_CHAT_MODELS catalog in src/providers/registry.ts. Update
the mixed-catalog discovery assertion in
tests/digitalocean-scaleway-provider.test.ts to verify that this model is
excluded while preserving the existing supported-model assertions.
Source: Path instructions
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e5f151216d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "llama-3.3-70b-instruct", | ||
| "mistral-medium-3.5-128b", | ||
| "mistral-small-3.2-24b-instruct-2506", | ||
| "pixtral-12b-2409", |
There was a problem hiding this comment.
Advertise image input for Pixtral
When a user selects scaleway/pixtral-12b-2409 for an image request, this allowlist exposes the multimodal model but the Scaleway registry entry provides no modelInputModalities metadata. Because /models supplies only generic OpenAI-shaped fields, catalog normalization consequently marks this row as input_modalities: ["text"], causing Codex App to reject image attachments before they reach the proxy. Add the model's ['text', 'image'] metadata to the canonical registry and cover the gathered catalog row in the provider test.
AGENTS.md reference: src/AGENTS.md:L18-L19
Useful? React with 👍 / 👎.
| "glm-5.1", | ||
| "glm-5", | ||
| // The API reference uses this native slash id in its Chat Completions example. | ||
| "meta-llama/Meta-Llama-3.1-8B-Instruct", |
There was a problem hiding this comment.
Disable reasoning controls for non-reasoning models
When Codex routes a request with reasoning.effort to an admitted non-reasoning model such as meta-llama/Meta-Llama-3.1-8B-Instruct, the DigitalOcean entry has neither a conservative reasoningEfforts: [] default nor a noReasoningModels classification. The catalog therefore advertises the full reasoning ladder and openai-chat forwards reasoning_effort, even though this model does not support that control; strict upstream validation can reject the request, while permissive handling silently ignores a user-visible option. Define the docs-backed reasoning models explicitly and suppress the field for the remainder, with a request regression test that supplies a reasoning effort.
AGENTS.md reference: src/AGENTS.md:L18-L19
Useful? React with 👍 / 👎.
Summary
Relates to #572. This PR intentionally does not close the umbrella issue.
Canonical preset evidence
https://inference.do-ai.run/v1, Bearer-authenticated/models, and the shared chat endpoint.https://api.scaleway.ai/v1, Bearer authentication, and the shared serverless API.Maintenance owner: @olddonkey. I am not affiliated with either provider.
Scope and safety
/modelsschemas expose only generic OpenAI-shaped rows, so discovery fails closed: a live row must also match the current first-party chat-model allowlist. Unknown rows are not promoted automatically.preserveCustomDestinationprevents registry promotion from retargeting keys already stored under a same-named custom provider. Discovery policy remains registry-only and is never serialized into user config or key-login metadata.Because this changes canonical credential destinations, explicit maintainer security review is requested.
Verification
bun run typecheckbun test tests/digitalocean-scaleway-provider.test.ts tests/provider-model-discovery-contract.test.ts tests/provider-registry-parity.test.ts— 56 pass, 0 failbun run test— 6873 pass, 8 skip, 0 failbun run privacy:scancd docs-site && bun run build— 206 pagesgit diff --checkSummary by CodeRabbit
New Features
Documentation